package Wallpaper::Tools;
$VERSION = sprintf "%.3f", 1 + substr(q$Revision: 159 $,9)/1000;

use Wallpaper::Configuration qw( %datastore );
use Image::Magick;
use Storable;
use File::Find;

use Wallpaper::Execute::Themer;
use Wallpaper::Execute::ConfigTweak;
use Wallpaper::Execute::Scaling;
use Wallpaper::Execute::BlurryTerminal;
use Wallpaper::Execute::Mangle;
use Wallpaper::Execute::Collage;

require Exporter;
@ISA       = qw( Exporter );
@EXPORT_OK = qw( decision_tree shifty timedata getfiletime getdir );

my $general_config = Wallpaper::Configuration->general;
my $debug          = $general_config->{ 'debug' };

use strict;

sub phoenix {

    store \%datastore, '/tmp/wallpaper.dump'; # Store current datastore info to disk before killing ourself.
    print "Cleaning up PID ... Byebye!\n";
    unlink( "$ENV{'HOME'}/.wall.pid" );
    exec($0) or die "Couldn't restart: $!\n";

}

sub timedata {
    my ( $class ) = shift;
    my ( $second, $minute, $hour, $dayOfMonth, $month, $yearOffset, $dayOfWeek, $dayOfYear, $daylightSavings ) = @_;

    my %time = ( second => $second,
                 minute => $minute,
                 hour   => $hour,
                 dom    => $dayOfMonth,
                 month  => $month,
                 year   => $yearOffset + 1900,
                 dow    => $dayOfWeek,
                 doy    => $dayOfYear,
                 dst    => $daylightSavings
               );
    bless \%time;
  return \%time;
} ## end sub timedata

=item * getfiletime

A simple function to return the last modified timestamp of a file.

Parmeter is a file, returns a hash of file data.

=cut

sub getfiletime {
    my $file = shift;
    my ( $dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks ) = stat( $file );

    my %data = ( dev     => $dev,
                 ino     => $ino,
                 mode    => $mode,
                 nlink   => $nlink,
                 uid     => $uid,
                 gid     => $gid,
                 rdev    => $rdev,
                 size    => $size,
                 atime   => $atime,
                 mtime   => $mtime,
                 ctime   => $ctime,
                 blksize => $blksize,
                 blocks  => $blocks
               );
    bless \%data;
  return \%data;
} ## end sub getfiletime

sub shifty {
    my ( $insert, $display ) = @_;

    my $old4    = $datastore{ $display }{ 'old4' };
    my $old3    = $datastore{ $display }{ 'old3' };
    my $old2    = $datastore{ $display }{ 'old2' };
    my $old1    = $datastore{ $display }{ 'old1' };
    my $current = $datastore{ $display }{ 'current' };
    my $next    = $datastore{ $display }{ 'next' };

    $datastore{ $display }{ 'old4' }    = $old3;
    $datastore{ $display }{ 'old3' }    = $old2;
    $datastore{ $display }{ 'old2' }    = $old1;
    $datastore{ $display }{ 'old1' }    = $current;
    $datastore{ $display }{ 'current' } = $next;
    $datastore{ $display }{ 'next' }    = $insert;

  return undef;
} ## end sub shifty

sub setroot {
    my ( $display ) = @_;

    system( "DISPLAY=:" . $display . " " . $general_config->{ 'exe_scale' } . " /dev/shm/walls/background" . $display . ".png" );

    # Clean up mess?!
    if ( $general_config->{ 'clean_shm' } ) {
        unlink( "/dev/shm/walls/background" . $display . ".png" );
    }
} ## end sub setroot

sub decision_tree {
    my $self = shift;

    my @items         = qw( 0 1 2 3 4 );
    my $alldisplay    = Wallpaper::Configuration->all_display;
    my $this_function = ( caller( 0 ) )[3];

    for my $primary ( @items ) {
        for my $secondary ( @items ) {

            my $display = $primary . "." . $secondary;

            if ( $alldisplay->{ $display }{ 'enable' } ) {
                my $image          = Image::Magick->new;
                my $display_config = Wallpaper::Configuration->display( $display );

                print "$self : $this_function (1) Processing $datastore{ $display }{ 'current' } on display $display\n" if $debug;
                die( "Cannot read current image : $datastore{ $display }{ 'current' }" ) if ( !-e $datastore{ $display }{ 'current' } );
                $image->Read( $datastore{ $display }{ 'current' } );    # Read in image for current file

                # Because this only exists in child process, getscheme saves
                # scheme to disks, and REAPER reads it into global configuation
                # once processing is done.
                $datastore{ $display }{ 'scheme' } = Wallpaper::Execute::getscheme( $self, $display, $image );
                store $datastore{ $display }{ 'scheme' }, "/tmp/wallpaper-scheme-$display.dump";

                if ( $alldisplay->{ $display }{ 'conky' }{ 'enable' } ) {
                    Wallpaper::Execute::config_tweak( $self, $display,
                                                      $display_config->{ 'conky' }{ 'template' },
                                                      $display_config->{ 'conky' }{ 'output' } );
                }

                if ( $alldisplay->{ $display }{ 'ob' }{ 'enable' } ) {
                    Wallpaper::Execute::config_tweak( $self, $display,
                                                      $display_config->{ 'ob' }{ 'template' },
                                                      $display_config->{ 'ob' }{ 'output' } );
                }

                if ( $alldisplay->{ $display }{ 'gtk' }{ 'enable' } ) {
                    Wallpaper::Execute::config_tweak( $self, $display,
                                                      $display_config->{ 'gtk' }{ 'template' },
                                                      $display_config->{ 'gtk' }{ 'output' } );
                }

                Wallpaper::Execute::doscale( $display, $image );

                if ( $alldisplay->{ $display }{ 'mangle' }{ 'enable' } ) {
                    Wallpaper::Execute::domangle( $self, $display, $image );
                }

                if ( $alldisplay->{ $display }{ 'collage' }{ 'enable' } ) {
                    Wallpaper::Execute::docollage( $display, $image );
                }

                if ( $alldisplay->{ $display }{ 'urxvt' }{ 'enable' } ) {
                    Wallpaper::Execute::doterminal( $display, $image );
                }

                # Write image do shared memory, and then display image, mangled or not...
                $image->Write( "/dev/shm/walls/background" . $display . ".png" );

                setroot( $display );

                if ( $alldisplay->{ $display }{ 'conky' }{ 'enable' } ) {
                    system( "killall -SIGUSR1 conky" );    # Tell conky to reread its config
                }
                if ( $alldisplay->{ $display }{ 'gtk' }{ 'enable' } ) {
                    system( "gconftool-2 -s --type string /desktop/gnome/interface/gtk_theme $datastore{ $display }{ 'gtk' }" );

                    # Tell Gnome to load new theme
                }
                if ( $alldisplay->{ $display }{ 'ob' }{ 'enable' } ) {
                    system( "killall -SIGUSR2 openbox" );    # Tell Openbox to load new theme
                }
            } ## end if ( $alldisplay->{ $display...
        } ## end for my $secondary ( @items)
    } ## end for my $primary ( @items)
} ## end sub decision_tree

=item * getdir

Getfiles simply gets the contents of a directory and returns an array of
filenames, minus . and ..  It assumed that only photos will be in your wallpaper
directories, so it doesn't do any further filtering.  If any subdirectories are
found, it will recurse through them as well.

This function accepts only one parameter, the full path to scan.  It returns an
array of filenames.

=cut

sub getdir {
    my ( $find_dir ) = @_;
    my ( @return );
    my $this_function = ( caller( 0 ) )[3];

    find(
        sub {
          return if ( -d $File::Find::name );
            my $file = $File::Find::name;
            $file =~ s/^$find_dir//g;
            $file =~ s/^\///g;
            push( @return, $file );
        },
        $find_dir . "/"
        );

    my $numreturn = scalar @return;
    print "                                  : $this_function (4) There are $numreturn files to pick from in $find_dir...\n" if ( $debug ge 4 );
  return @return;
} ## end sub getdir

1;
